/********************************************************************************
 * Copyright (c)2016-2020, ShenZhen WanJiaAn Technology CO.,LTD.
 * All Rights Reserved.
 *
 * File Name     : hi1131s.c
 * Author        : joki.zhu
 * Date          : 2020-07-06
 *
 * Record        :
 * 1.Date        : 2020-07-06
 *   Author      : joki.zhu
 *   Modification: Created file
 ********************************************************************************/
#include "sys/types.h"
#include "sys/time.h"
#include "unistd.h"
#include "fcntl.h"
#include "sys/statfs.h"
#include "limits.h"
#include "los_event.h"
#include "los_printf.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
//#include "eth_drv.h"
#include "arch/perf.h"
#include "fcntl.h"
#include "fs/fs.h"
#include "stdio.h"
#include "shell.h"
#include "hisoc/uart.h"
#include "vfs_config.h"
#include "disk.h"
#include "los_cppsupport.h"
#include "linux/fb.h"
#include "securec.h"
/*Hi1131 modify add */
#include "los_event.h"
#include "wpa_supplicant/wpa_supplicant.h"
#include "hostapd/hostapd_if.h"
#include <mmc/host.h>
#include "hisilink_lib.h"
#include "hilink_link.h"
#include "driver_hisi_lib_api.h"
#include <linux/completion.h>
#include <linux/mtd/mtd.h>
#include <pm/hi_type.h>
#include "hi_uartmsg.h"
#include "console.h"
#include "hisoc/uart.h"
#include "uart.h"

#include "DevWifi.h"
#include "app_common.h"
#include "DevLed.h"
#include "DevKey.h"
#include "SoundWave.h"
#include "PowerManager.h"
#include "partition_table.h"
#include "Audio.h"
#include "System.h"
#include "Net.h"
#include "Upgrade.h"

#ifdef YD_PROTOCOL
#include "dot_define.h"
#include "DOTSdkAPI.h"
#endif

#define WPA_SUPPLICANT_CONFIG_PATH  "/config/etc/hisi_wifi/wifi/wpa_supplicant.conf"

HI_UARTMSG_SOCPOWER_TYPE_E g_enSocPowerType = HI_UARTMSG_POWER_BUTT;
static char gs_wpasupplicantRunOk = 0;
static char gs_wakeFlag = 0;
static WIFI_CONFIG_STATUS_E gs_enWifiConfigState = WIFI_CONFIG_NONE;

static enum wpa_event gs_wpaEvent = WPA_EVT_DISCONNECTED;
static char gs_bStopStaMode = 0;
static char gs_bDhcpOk = 0;
static WIFI_MODE_E gs_enWifiMode = WIFI_MODE_NONE;

#ifdef LOSCFG_DRIVERS_MTD_SPI_NOR
extern struct mtd_info *spinor_mtd;
#endif

typedef enum
{
	HSL_STATUS_UNCREATE,
	HSL_STATUS_CREATE,
	HSL_STATUS_RECEIVE,
	HSL_STATUS_CONNECT,
	HSL_STATUS_BUTT
}hsl_status_enum;

typedef enum
{
	HILINK_STATUS_UNCREATE,
	HILINK_STATUS_RECEIVE, //hilink处于接收组播阶段
	HILINK_STATUS_CONNECT, //hilink处于关联阶段
	HILINK_STATUS_BUTT
}hilink_status_enum;

struct timer_list   hisi_dhcp_timer;
unsigned int        check_ip_loop = 0;

struct netif       *pwifi = NULL;


/* 从启动dhcp，间隔1秒查询IP是否获取，30秒未获取IP执行去关联动作 */
#define             DHCP_CHECK_CNT      30
#define             DHCP_CHECK_TIME     1000

#define WLAN_FILE_STORE_MIN_SIZE             (0)
#define WLAN_FILE_STORE_MID_SIZE             (0x30000)
#define WLAN_FILE_STORE_MAX_SIZE             (0x70000)
#define WLAN_FILE_STORE_BASEADDR             (0x750000)

#define             WIFI_IRQ                                    (54)   //GPIO6
#define             WIFI_SDIO_INDEX                             (1)

#ifdef HISI_WIFI_PLATFORM_HI3516EV100
#define             WIFI_DATA_INTR_GPIO_GROUP                   (3)
#define             WIFI_DATA_INTR_GPIO_OFFSET                  (2)

#define             HOST_WAK_DEV_GPIO_GROUP                     (3)
#define             HOST_WAK_DEV_GPIO_OFFSET                    (0)

#define             WIFI_WAK_FLAG_GPIO_GROUP                    (3)
#define             WIFI_WAK_FLAG_GPIO_OFFSET                   (1)

#define             DEV_WAK_HOST_GPIO_GROUP                     (3)
#define             DEV_WAK_HOST_GPIO_OFFSET                    (3)

#define REG_MUXCTRL_WIFI_DATA_INTR_GPIO_MAP             (IO_MUX_REG_BASE + 0x08C)
#define REG_MUXCTRL_HOST_WAK_DEV_GPIO_MAP               (IO_MUX_REG_BASE + 0x094)
#define REG_MUXCTRL_WIFI_WAK_FLAG_GPIO_MAP              (IO_MUX_REG_BASE + 0x090)
#define REG_MUXCTRL_DEV_WAK_HOST_GPIO_MAP               (IO_MUX_REG_BASE + 0x088)
#else
#define             WIFI_DATA_INTR_GPIO_GROUP                   (6)
#define             WIFI_DATA_INTR_GPIO_OFFSET                  (7)

#define             HOST_WAK_DEV_GPIO_GROUP                     (5)
#define             HOST_WAK_DEV_GPIO_OFFSET                    (1)

#define             DEV_WAK_HOST_GPIO_GROUP                     (8)
#define             DEV_WAK_HOST_GPIO_OFFSET                    (6)

#define REG_MUXCTRL_WIFI_DATA_INTR_GPIO_MAP        (IO_MUX_REG_BASE + 0x1200068)
#define REG_MUXCTRL_HOST_WAK_DEV_GPIO_MAP        (IO_MUX_REG_BASE + 0x1200044)
//#define REG_MUXCTRL_WIFI_WAK_FLAG_GPIO_MAP        (IO_MUX_REG_BASE + 0x1200050)  //使用PWR_WAKEUP识别，读寄存器
#define REG_MUXCTRL_DEV_WAK_HOST_GPIO_MAP        (IO_MUX_REG_BASE + 0x1200050)
#endif

#define REG_MUXCTRL_SDIO0_CLK_MAP          (IO_MUX_REG_BASE + 0x7c)
#define REG_MUXCTRL_SDIO0_DETECT_MAP        (IO_MUX_REG_BASE + 0x68)
#define REG_MUXCTRL_SDIO0_CDATA1_MAP        (IO_MUX_REG_BASE + 0x74)
#define REG_MUXCTRL_SDIO0_CDATA0_MAP        (IO_MUX_REG_BASE + 0x70)
#define REG_MUXCTRL_SDIO0_CDATA3_MAP        (IO_MUX_REG_BASE + 0x80)
#define REG_MUXCTRL_SDIO0_CCMD_MAP        (IO_MUX_REG_BASE + 0x78)
#define REG_MUXCTRL_SDIO0_CDATA2_MAP        (IO_MUX_REG_BASE + 0x84)

#define REG_MUXCTRL_SDIO1_CLK_MAP           (0x112c0048)
//#define REG_MUXCTRL_SDIO1_DETECT_MAP        (IO_MUX_REG_BASE + 0x0a8)
#define REG_MUXCTRL_SDIO1_CDATA1_MAP        (0x112c0060)
#define REG_MUXCTRL_SDIO1_CDATA0_MAP        (0x112c0064)
#define REG_MUXCTRL_SDIO1_CDATA3_MAP        (0x112c0058)
#define REG_MUXCTRL_SDIO1_CCMD_MAP          (0x112c004C)
#define REG_MUXCTRL_SDIO1_CDATA2_MAP        (0x112c005C)

extern void mcu_uart_proc();
extern void hisi_wifi_shell_cmd_register(void);
extern void HI_HAL_MCUHOST_WiFi_Clr_Flag(void);
extern void HI_HAL_MCUHOST_WiFi_Power_Set(unsigned char val);
extern void HI_HAL_MCUHOST_WiFi_Rst_Set(unsigned char val);
extern unsigned char hsl_demo_get_status(void);
extern hsl_result_stru* hsl_demo_get_result(void);
extern unsigned char hilink_demo_get_status(void);
extern hsl_result_stru* hilink_demo_get_result(void);
extern void hisi_reset_addr(void);
extern int hilink_demo_online(hilink_s_result* pst_result);
extern int hsl_demo_online(hsl_result_stru* pst_params);

/*Hi1131 modify end */


#ifndef HISYSLINK_ENABLE

void hi_rf_customize_init(void)
{
	struct _hisi_rf_customize_stru *pst_customize_handler = hisi_get_customize_info_handler();
	if (NULL == pst_customize_handler)
	{
		dprintf("hi_rf_customize_init::error handler null\n");
		return;
	}

#ifndef WIFI_TEST_MODE 
	/*11b scaling 功率，共4字节，低字节到高字节对应1m、2m、5.5m、11m，值越大，11b模式发射功率越高*/
	pst_customize_handler->l_11b_scaling_value              = 0x9c9c9c9c;
	/*11g scaling 功率，共4字节，低字节到高字节对应6m、9m、12m、18m，值越大，11g模式发射功率越高*/
	pst_customize_handler->l_11g_u1_scaling_value           = 0x5b5b5b5b;
	/*11g scaling 功率，共4字节，低字节到高字节对应24m、36m、48m、54m，值越大，11g模式发射功率越高*/
	pst_customize_handler->l_11g_u2_scaling_value           = 0x665b5b5b;
	/*11n 20m scaling 功率，共4字节，低字节到高字节对应mcs4、mcs5、mcs6、mcs7，值越大，11n模式发射功率越高*/
	pst_customize_handler->l_11n_20_u1_scaling_value        = 0x57575757;
	/*11n 20m scaling 功率，共4字节，低字节到高字节对应mcs0、mcs1、mcs2、mcs3，值越大，11n模式发射功率越高*/
	pst_customize_handler->l_11n_20_u2_scaling_value        = 0x5c5c5757;
	/*11n 40m scaling 功率，共4字节，低字节到高字节对应mcs4、mcs5、mcs6、mcs7，值越大，11n模式发射功率越高*/
	pst_customize_handler->l_11n_40_u1_scaling_value        = 0x5a5a5a5a;
	/*11n 40m scaling 功率，共4字节，低字节到高字节对应mcs0、mcs1、mcs2、mcs3，值越大，11n模式发射功率越高*/
	pst_customize_handler->l_11n_40_u2_scaling_value        = 0x5d5d5a5a;
	
	/*1-4信道upc功率调整，值越大，该信道功率越高*/
	pst_customize_handler->l_ban1_ref_value                  = 50;
	/*5-9信道upc功率调整，值越大，该信道功率越高*/
	pst_customize_handler->l_ban2_ref_value                  = 49;
	/*10-13信道upc功率调整，值越大，该信道功率越高*/
	pst_customize_handler->l_ban3_ref_value                  = 50;

	/*40M带宽bypass，置1禁用40M带宽，写0使用40M带宽*/
	pst_customize_handler->l_disable_bw_40                   = 1;
	/*低功耗开关，写1打开低功耗，写0关闭低功耗*/
	pst_customize_handler->l_pm_switch                       = 1;
	/*dtim设置, 范围1-10*/
	pst_customize_handler->l_dtim_setting                    = 10;
	/*远距离弱信号3db增强开关默认打开，1打开，0关闭*/
	pst_customize_handler->l_limit_pow_setting               = 1;
	/*0:默认速率调整 1:优化速率调整，不降协议 */
	pst_customize_handler->l_rssi_descend_protocol_limit     = 1;

	/*如需定制化，请置1，否则请置0*/
	pst_customize_handler->l_customize_enable                = 1;	
#else // test
	printf("\n\n<<=====WIFI_TEST_MODE===>>\n\n");
    /*11b scaling 功率，共4字节，低字节到高字节对应1m、2m、5.5m、11m，值越大，11b模式发射功率越高*/
    pst_customize_handler->l_11b_scaling_value              = 0x5e5e5e5e;
    /*11g scaling 功率，共4字节，低字节到高字节对应6m、9m、12m、18m，值越大，11g模式发射功率越高*/
    pst_customize_handler->l_11g_u1_scaling_value           = 0x4e4e4e4e;
    /*11g scaling 功率，共4字节，低字节到高字节对应24m、36m、48m、54m，值越大，11g模式发射功率越高*/
    pst_customize_handler->l_11g_u2_scaling_value           = 0x474e4e4e;
    /*11n 20m scaling 功率，共4字节，低字节到高字节对应mcs4、mcs5、mcs6、mcs7，值越大，11n模式发射功率越高*/
    pst_customize_handler->l_11n_20_u1_scaling_value        = 0x38383838;
    /*11n 20m scaling 功率，共4字节，低字节到高字节对应mcs0、mcs1、mcs2、mcs3，值越大，11n模式发射功率越高*/
    pst_customize_handler->l_11n_20_u2_scaling_value        = 0x3e3e3838;
    /*11n 40m scaling 功率，共4字节，低字节到高字节对应mcs4、mcs5、mcs6、mcs7，值越大，11n模式发射功率越高*/
    pst_customize_handler->l_11n_40_u1_scaling_value        = 0x3b3b3b3b;
    /*11n 40m scaling 功率，共4字节，低字节到高字节对应mcs0、mcs1、mcs2、mcs3，值越大，11n模式发射功率越高*/
    pst_customize_handler->l_11n_40_u2_scaling_value        = 0x3e3e3b3b;
	/*1-4信道upc功率调整，值越大，该信道功率越高*/
	pst_customize_handler->l_ban1_ref_value                  = 50;
	/*5-9信道upc功率调整，值越大，该信道功率越高*/
	pst_customize_handler->l_ban2_ref_value                  = 40;
	/*10-13信道upc功率调整，值越大，该信道功率越高*/
	pst_customize_handler->l_ban3_ref_value                  = 40;
	/*40M带宽bypass，置1禁用40M带宽，写0使用40M带宽*/
	pst_customize_handler->l_disable_bw_40                   = 1;
	/*低功耗开关，写1打开低功耗，写0关闭低功耗*/
	pst_customize_handler->l_pm_switch                       = 0;
	/*dtim设置, 范围1-10*/
	pst_customize_handler->l_dtim_setting                    = 10;
	/*远距离弱信号3db增强开关默认打开，1打开，0关闭*/
	pst_customize_handler->l_limit_pow_setting               = 1;
	/*0:默认速率调整 1:优化速率调整，不降协议 */
	pst_customize_handler->l_rssi_descend_protocol_limit     = 1;

	/*如需定制化，请置1，否则请置0*/
	pst_customize_handler->l_customize_enable                = 1;
#endif

}
void hi_wifi_register_init(void)
{
	unsigned int value = 0;

	/*配置管脚复用*/
	if (0 == WIFI_SDIO_INDEX)
	{
		value = 0x0001;
		writel(value, REG_MUXCTRL_SDIO0_CLK_MAP);
		//writel(value, REG_MUXCTRL_SDIO0_DETECT_MAP);
		writel(value, REG_MUXCTRL_SDIO0_CDATA1_MAP);
		writel(value, REG_MUXCTRL_SDIO0_CDATA0_MAP);
		writel(value, REG_MUXCTRL_SDIO0_CDATA3_MAP);
		writel(value, REG_MUXCTRL_SDIO0_CCMD_MAP);
		writel(value, REG_MUXCTRL_SDIO0_CDATA2_MAP);
	}
	else if (1 == WIFI_SDIO_INDEX)
	{
		value = 0x134;
		writel(0x1D54, REG_MUXCTRL_SDIO1_CLK_MAP);
		writel(value, REG_MUXCTRL_SDIO1_CDATA1_MAP);
		writel(value, REG_MUXCTRL_SDIO1_CDATA0_MAP);
		writel(value, REG_MUXCTRL_SDIO1_CDATA3_MAP);
		writel(value, REG_MUXCTRL_SDIO1_CCMD_MAP);
		writel(value, REG_MUXCTRL_SDIO1_CDATA2_MAP);
	}

	value = 0x0;
	writel(value, REG_MUXCTRL_WIFI_DATA_INTR_GPIO_MAP);
	writel(value, REG_MUXCTRL_HOST_WAK_DEV_GPIO_MAP);
	//    writel(value, REG_MUXCTRL_WIFI_WAK_FLAG_GPIO_MAP);  通过PWR_WAKEUP识别
	writel(value, REG_MUXCTRL_DEV_WAK_HOST_GPIO_MAP);
}

void hi_wifi_power_set(unsigned char val)
{
	HI_UARTMSG_SendData(HI_UARTMSG_S2M_SET_WIFI_POWER, &val, 1);
}
void hi_wifi_rst_set(unsigned char val)
{
	HI_UARTMSG_SendData(HI_UARTMSG_S2M_SET_WIFI_RST, &val, 1);
}

void himci_wifi_sdio_detect_trigger(void)
{
	unsigned int reg_value = 0;

	struct mmc_host *mmc = NULL;
	mmc = get_mmc_host(WIFI_SDIO_INDEX);
	struct himci_host *host = (struct himci_host *)mmc->priv;

	if (0 == WIFI_SDIO_INDEX)
	{
		writel(0x0001, REG_MUXCTRL_SDIO0_DETECT_MAP);
	}
	else if (1 == WIFI_SDIO_INDEX)
	{
#if 0
		reg_value = readl(REG_MUXCTRL_SDIO1_DETECT_MAP);
		if (0X0002 == reg_value)
		{
			writel(0x0, REG_MUXCTRL_SDIO1_DETECT_MAP);
			msleep(500);//wait sdio card remove
		}
		writel(0X0002, REG_MUXCTRL_SDIO1_DETECT_MAP);
#else/* mmc rescan 软件实现，需要有对应的LiteOS版本并做相关改动 */
		hisi_sdio_rescan(WIFI_SDIO_INDEX);
#endif
	}
	/* SDIO2硬件上无detect管脚，mmc rescan只能通过软件方式实现，SDIO2的mmc index为3，需要有对应的LiteOS版本并做相关改动 */
	else if (3 == WIFI_SDIO_INDEX)
	{
		hisi_sdio_rescan(WIFI_SDIO_INDEX);
	}
#if 0/* 若使用软件方式实现mmc rescan 请将以下这行代码注释 */
	hi_mci_pre_detect_card(host);
#endif
	//    hi_mci_pad_ctrl_cfg(host, SIGNAL_VOLT_1V8);
}

void hi_host_pow_off(void)
{
	msleep(110);//增加延时，否则导致日志打印不全
	HI_UARTMSG_SendData(HI_UARTMSG_S2M_SOC_POWER_DOWN, NULL, 0);
}

int hi_flash_erase(unsigned long   ul_start,unsigned long   ul_size)
{
	struct erase_info   st_erase;
	int            l_ret;

	if ((ul_size <= 0) || (NULL == spinor_mtd->erase))
	{
		printf( "ul_size is:%d ,spinor_mtd->erase:0x%p\n", ul_size, spinor_mtd->erase);
		return -1;
	}
	memset(&st_erase, 0, sizeof(struct erase_info));

	st_erase.mtd             = spinor_mtd;
	st_erase.callback        = NULL;
	st_erase.fail_addr       = -1LL;
	st_erase.addr            = ul_start;
	st_erase.len             = ul_size;
	st_erase.time            = 1;
	st_erase.retries         = 1;
	st_erase.dev             =0;
	st_erase.cell            = 0;
	st_erase.priv            =0;
	st_erase.state           = 0;
	st_erase.next            = NULL;
	st_erase.scrub           = 0;

	l_ret = spinor_mtd->erase(spinor_mtd, &st_erase);
	if (0 != l_ret)
	{
		printf( "spiflash_erase_proc erase error,lret[%u]\n", l_ret);
	}
	printf("flash_erase ok .ul_start = 0x%x\n",ul_start);
	return l_ret;
}

int hi_flash_write(void *p_memaddr,unsigned long   ul_start,unsigned long   ul_size)
{
	printf("%s\n", __FUNCTION__);
	unsigned int  ul_retlen;
	int    l_ret;

	if ((ul_size <= 0) || (NULL == spinor_mtd->write))
	{
		printf( "ul_size is:%d ,spinor_mtd->write:0x%p\n", ul_size, spinor_mtd->write);
		return -1;
	}

	l_ret =  spinor_mtd->write(spinor_mtd, ul_start, ul_size, &ul_retlen, p_memaddr);
	if (0 != l_ret)
	{
		printf( "spiflash_write_proc write error,lret[%u],ul_retlen[%u]\n", l_ret, ul_retlen);
	}
	printf("flash_write ok  ul_start[0x%x] ul_size[0x%x] ul_retlen[0x%x] p_memaddr[0x%x]\n",ul_start,ul_size,ul_retlen,p_memaddr);
	return l_ret;
}

int hi_flash_read(void *p_memaddr,unsigned long   ul_start,unsigned long   ul_size)
{
	printf("%s\n", __FUNCTION__);
	unsigned int ul_retlen;
	int   l_ret;

	if ((ul_size <= 0) || (NULL == spinor_mtd->read))
	{
		printf( "ul_size is:%d ,spinor_mtd->read:0x%p\n", ul_size, spinor_mtd->read);
		return -1;
	}

	l_ret = spinor_mtd->read(spinor_mtd, ul_start, ul_size, &ul_retlen, p_memaddr);
	if (0 != l_ret)
	{
		printf("spiflash_read_proc read error,lret[%u],ul_retlen[%u]\n", l_ret, ul_retlen);
	}
	printf("flash_read ok  ul_start = 0x%x\n",ul_start);
	return l_ret;
}

void hi_wifi_board_info_register(void)
{
	struct board_info *wlan_board_info = hisi_get_board_info_handler();
	if (NULL == wlan_board_info)
	{
		dprintf("wifi_board_info is NULL!\n");
		return;
	}

	wlan_board_info->wlan_irq = WIFI_IRQ;

	wlan_board_info->wifi_data_intr_gpio_group = WIFI_DATA_INTR_GPIO_GROUP;
	wlan_board_info->wifi_data_intr_gpio_offset = WIFI_DATA_INTR_GPIO_OFFSET;

	wlan_board_info->dev_wak_host_gpio_group = DEV_WAK_HOST_GPIO_GROUP;
	wlan_board_info->dev_wak_host_gpio_offset = DEV_WAK_HOST_GPIO_OFFSET;

	wlan_board_info->host_wak_dev_gpio_group = HOST_WAK_DEV_GPIO_GROUP;
	wlan_board_info->host_wak_dev_gpio_offset = HOST_WAK_DEV_GPIO_OFFSET;

	wlan_board_info->wifi_power_set = hi_wifi_power_set;
	wlan_board_info->wifi_rst_set = hi_wifi_rst_set;
	wlan_board_info->wifi_sdio_detect = himci_wifi_sdio_detect_trigger;
	wlan_board_info->host_pow_off = hi_host_pow_off;
}

void hi_flash_iface_info_register(void)
{
	struct flash_iface_to_user *flash_ops_info = hisi_get_flash_info_handler();
	if (NULL == flash_ops_info)
	{
		dprintf("flash_ops_info is NULL!\n");
		return NULL;
	}
	flash_ops_info->fcb_flash_erase = hi_flash_erase;
	flash_ops_info->fcb_flash_write = hi_flash_write;
	flash_ops_info->fcb_flash_read = hi_flash_read;
}

void hi_wifi_check_wakeup_flag(void)
{
	int wak_flag = 0;

#ifdef _TYPE_UART_MSG    //使用 UART 方式查询上电方式
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
	HI_U32 timeoutMs = 1000;
	HI_S32 ret;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_POWER_ON_TYPE;
	stWaitMsg.dataLen = 3;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_POWER_ON_TYPE_ACK;
	LOGD("test\n");
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret)
	{
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
	}
	else
	{
        char bSleepMode = 0;
        DevConfigGetWifiSleepMode(&bSleepMode);
        wak_flag = bSleepMode;
        DevConfigSetWifiSleepMode(0);

	    g_enSocPowerType = stWaitMsg.data[0];
        if (HI_UARTMSG_POWER_REMOTE == stWaitMsg.data[0]) {
            wak_flag = 1;
        } else if (HI_UARTMSG_POWER_NORMAL == stWaitMsg.data[0]) {
            wak_flag = 0;
        }
	}
	LOGD("HI_UARTMSG_S2M_GET_POWER_ON_TYPE %d\n", stWaitMsg.data[0]);
	
#elif _TYPE_PMC_PWR_WAKEUP    //使用PMC pwr_wakeup 管脚作为唤醒标志
	unsigned int value = 0;
	value = readl(0x120f0008);
	wak_flag = (value & (1 << 8)) ? 1 : 0; //取值0或1

	HI_UARTMSG_SendData(HI_UARTMSG_S2M_CLR_MCU_WAKE_FLAG, NULL, 0);
#else   // 普通 GPIO
	gpio_dir_config(WIFI_WAK_FLAG_GPIO_GROUP, WIFI_WAK_FLAG_GPIO_OFFSET, 0);
	wak_flag = gpio_read(WIFI_WAK_FLAG_GPIO_GROUP, WIFI_WAK_FLAG_GPIO_OFFSET);
	HI_HAL_MCUHOST_WiFi_Clr_Flag();
#endif

	gs_wakeFlag = wak_flag;
    
	hisi_wlan_resume_state_set(wak_flag);
}

struct databk_addr_info *hi_wifi_databk_info_cb(void)
{
	printf("%s\n", __FUNCTION__);
	/* 暂时写死，由应用侧补齐 */
	struct databk_addr_info *wlan_databk_addr_info = NULL;
	wlan_databk_addr_info = malloc(sizeof(struct databk_addr_info));
	if (NULL == wlan_databk_addr_info)
	{
		dprintf("hi_wifi_databk_info_cb:wlan_databk_addr_info is NULL!\n");
		return NULL;
	}
	memset(wlan_databk_addr_info, 0, sizeof(struct databk_addr_info));
	//wlan_databk_addr_info->databk_addr = 0x7d0000;
	wlan_databk_addr_info->databk_addr = FLASH_WIFIBAK_OFFSET;
	wlan_databk_addr_info->databk_length = 0x10000;
	wlan_databk_addr_info->get_databk_info = NULL;
	return wlan_databk_addr_info;
}

void hi_wifi_register_backup_addr(void)
{
	printf("%s\n", __FUNCTION__);
	struct databk_addr_info *wlan_databk_addr_info = hisi_wlan_get_databk_addr_info();
	if (NULL == wlan_databk_addr_info)
	{
		dprintf("hi_wifi_register_backup_addr:wlan_databk_addr_info is NULL!\n");
		return;
	}
	/* 暂时写死，由应用侧补齐 */
	//wlan_databk_addr_info->databk_addr = 0x7d0000;
	wlan_databk_addr_info->databk_addr = FLASH_WIFIBAK_OFFSET;
	wlan_databk_addr_info->databk_length = 0x10000;
	wlan_databk_addr_info->get_databk_info = hi_wifi_databk_info_cb;
}

void hi_wifi_no_fs_init(void)
{
	hisi_wlan_no_fs_config(WLAN_FILE_STORE_BASEADDR, WLAN_FILE_STORE_MIN_SIZE);
}

void hi_wifi_pre_proc(void)
{
	hi_wifi_register_init();
	hi_wifi_board_info_register();
	hi_wifi_check_wakeup_flag();
	hi_wifi_register_backup_addr();
	hi_wifi_no_fs_init();
	hi_rf_customize_init();
	hi_flash_iface_info_register();
}
struct completion  dhcp_complet;
struct completion  wpa_ready_complet;

int hi_check_dhcp_success(void)
{
	int             ret    = 0;

	ret = dhcp_is_bound(pwifi);
	if (0 == ret)
	{
		/* IP获取成功后通知wifi驱动 */
		dprintf("\n\n DHCP SUCC\n\n");
		gs_bDhcpOk = 1;
		hisi_wlan_ip_notify(HISI_STA_MODE, HISI_DHCP_IP_SET);
		if (HSL_STATUS_UNCREATE != hsl_demo_get_status())
		{
			complete(&dhcp_complet);
		}
		del_timer(&hisi_dhcp_timer);
		return 0;
	}

	if (check_ip_loop++ > DHCP_CHECK_CNT)
	{
		/* IP获取失败执行去关联 */
		dprintf("\n\n DHCP FAILED\n\n");
		gs_bDhcpOk = 0;
		wpa_cli_disconnect();
		del_timer(&hisi_dhcp_timer);
		return 0;
	}

	/* 重启查询定时器 */
	add_timer(&hisi_dhcp_timer);
	return 0;
}

extern int hsl_demo_connect(hsl_result_stru* pst_params);
extern int hilink_demo_connect(hilink_s_result* pst_result);
void hisi_wifi_event_cb(enum wpa_event event)
{
	unsigned char    uc_status;
	hsl_result_stru *pst_hsl_result;
	hilink_s_result *pst_hilink_result;
	printf("wifi_event_cb,event:%d\n",event);

	if(pwifi == 0)
		return ;

	switch(event) {
	case WPA_EVT_SCAN_RESULTS:
		printf("Scan results available\n");
		break;
	case WPA_EVT_CONNECTED:
		printf("WiFi: Connected\n");
		gs_wpaEvent = WPA_EVT_CONNECTED;
		/* 启动dhcp获取IP */
		netifapi_dhcp_stop(pwifi);
		netifapi_dhcp_start(pwifi);

		/* 查询IP是否获取 */
		check_ip_loop = 0;
		init_timer(&hisi_dhcp_timer);
		hisi_dhcp_timer.expires = LOS_MS2Tick(DHCP_CHECK_TIME);
		hisi_dhcp_timer.function = hi_check_dhcp_success;
		add_timer(&hisi_dhcp_timer);
		msleep(500);
		break;
	case WPA_EVT_DISCONNECTED:
		printf("WiFi: disconnect\n");
		gs_wpaEvent = WPA_EVT_DISCONNECTED;
		netifapi_dhcp_stop(pwifi);
		hisi_reset_addr();
		hisi_wlan_ip_notify(HISI_STA_MODE, HISI_DHCP_IP_DEL);
		break;
	case WPA_EVT_ADDIFACE:
		gs_wpasupplicantRunOk = 1;
		complete(&wpa_ready_complet);
		//wpa_supplicant创建成功
		/* 判断是否为hisi_link创建的WPA成功 */
		uc_status = hsl_demo_get_status();
		printf("hsl_status=%d\n",uc_status);
		if (HSL_STATUS_CONNECT == uc_status)
		{
			pst_hsl_result = hsl_demo_get_result();
			if (NULL != pst_hsl_result)
			{
				hsl_demo_connect(pst_hsl_result);
				break;
			}
		}
		break;
	case WPA_EVT_WRONGKEY:
		printf("maybe key is wrong\n");
		break;
	default:
		break;
	}
}

void hisi_reset_addr(void)
{
	ip4_addr_t        st_gw;
	ip4_addr_t        st_ipaddr;
	ip4_addr_t        st_netmask;
	struct netif    *pst_lwip_netif;

	IP4_ADDR(&st_gw, 0, 0, 0, 0);
	IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
	IP4_ADDR(&st_netmask, 0, 0, 0, 0);

	pst_lwip_netif = netif_find("wlan0");
	if (HISI_NULL == pst_lwip_netif)
	{
		HISI_PRINT_ERROR("cmd_start_hapd::Null param of netdev");
		return;
	}

	/* wpa_stop后，重新设置netif的网关和mac地址 */
	netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
}

extern int hsl_demo_init(void);
extern int hilink_demo_init(void);
void hisi_wifi_hostapd_event_cb(enum hostapd_event event)
{
	unsigned char uc_status;
	struct netif  *pst_lwip_netif;

	printf("hostapd_event=%d\n",event);
	switch(event)
	{
	case HOSTAPD_EVT_ENABLED:
		//hostapd创建成功
		pst_lwip_netif = netif_find("wlan0");
		if (NULL == pst_lwip_netif)
		{
			dprintf("error: hisi_wifi_hostapd_event_cb\n");
		}
		netifapi_netif_set_up(pst_lwip_netif);
		if (0 == netifapi_dhcps_start(pst_lwip_netif, NULL, 0))
		{
			hisi_wlan_ip_notify(HISI_AP_MODE, HISI_DHCP_IP_SET);
		}
		/* 判断是否起hisilink */
		uc_status = hsl_demo_get_status();
		printf("hsl_status=%d\n",uc_status);
		if (HSL_STATUS_RECEIVE == uc_status)
		{
			hsl_demo_init();
		}
		break;
	case HOSTAPD_EVT_DISABLED:
		//hostapd删除成功
		hisi_reset_addr();
		break;
	case HOSTAPD_EVT_CONNECTED:
		//用户关联成功
		break;
	case HOSTAPD_EVT_DISCONNECTED:
		//用户去关联
		break;
	default:
		break;
	}
}

static int hi1131_wifi_init(void)
{
	UINT32 uwRet = 0;

	LOGD("hisi_wifi_shell_cmd_register init ...\n");
	hisi_wifi_shell_cmd_register();

	/*check system bootup or wakeup*/
	hi_wifi_pre_proc();

	LOGD("hi1131 wifi start \n");

	wpa_register_event_cb(hisi_wifi_event_cb);
	hostapd_register_event_cb(hisi_wifi_hostapd_event_cb);
	uwRet = hisi_wlan_wifi_init(&pwifi);

	LOGW("uwRet:%d\n", uwRet);
	/*uwRet = 0 :非待机唤醒时，驱动初始化成功，客户进行wpa_supplicant_start wpa_cli_scan wpa_cli_connect DHCP动作
	  待机唤醒时,驱动初始化及恢复成功，自动恢复到关联成功以及IP地址恢复的状态
	  uwRet = 1 :待机唤醒时，恢复失败(FLASH数据异常，相关接口已经暴露)，Hi1131发现异常退出待机恢复，并进行驱动初始化
	  以及wpa_supplicant_start动作，客户进行wpa_cli_scan wpa_cli_connect DHCP动作
	  uwRet = -1或其它值，表示驱动异常或硬件异常，请执行reset，确认是否能解决。
	  */
	if(0 != uwRet && 1 != uwRet)
	{
		LOGE("fail to start hi1131 wifi\n");
		if(pwifi != NULL) {
			hisi_wlan_wifi_deinit();
		}
		
		SystemReboot("hi1131 wifi init failed\n");

		return -1;
	}

	init_completion(&wpa_ready_complet);

#ifdef WIFI_TEST_MODE
    return 0;
#endif

	//if (!gs_wakeFlag)
	{
#ifdef Hi1131_SDK
		char *mac_addr[] = {"3E","22","15","05","31","35"};
		cmd_set_macaddr(6,mac_addr);
#endif
        if (!gs_wakeFlag)
        {
            //uwRet = wpa_supplicant_start("wlan0", "hisi", WPA_SUPPLICANT_CONFIG_PATH);
            uwRet = wpa_supplicant_start("wlan0", "hisi", NULL);
            if(0 != uwRet) {
                LOGE("fail to start wpa_supplicant\n");
                return -1;
            }
        }		
        wpa_register_event_cb(hisi_wifi_event_cb);
	}

    /* check wifi wakeup reason */
    int quickLinkFlag = -1;
    quickLinkFlag = WifiGetWakeupReason();
    if (quickLinkFlag == 0) {
        if (gs_wakeFlag == 1) {
            gs_wpasupplicantRunOk = 1;
        }
        gs_wakeFlag = 0;
    }
    
    return uwRet;
}


int wifi_get_scan_results()
{
    cmd_wpa_scan_results();
}

/* solve chinese ssid */
static char *wifi_ssid_conver(char *before, char *bHex)
{
    unsigned int i;
    char *ch1;
    int flag_hex = 0;              
    static char after[32 * 4 + 1];
    
    memset(after, 0, 32 * 4 + 1);
    if (before == NULL || bHex ==NULL) {
        return after;
    }

    /* Whether it is GBK code */
    for (i = 0; i < strlen(before); i++) 
    {
        if (before[i] < 32 || before[i] > 127) {
            flag_hex = 1;
            break;
        }
    }
    ch1 = &after[0];
    if (flag_hex) /* GBK, without '"' */
    {
        *bHex = 1;
        i = 0;
        for (;;) {
            if (before[i] == 0) {
                break;
            }
            if (before[i] < 32 || before[i] > 127) {
                sprintf(ch1, "\\x%02x", (unsigned char)before[i]);
                ch1 += 4;
            } else {
                sprintf(ch1, "%c", (unsigned char)before[i]);
                ch1 += 1;
            }
            i++;
        }
    }
    else /* ASCII SSID, need '"' */
    {
        *bHex = 0;
#ifdef __HuaweiLite__
        strcpy(after, before);
#else
        after[0] ='"';
        strcpy(after+1, before);
        after[strlen(before) + 1] = '"';
#endif /* __HuaweiLite__ */
    }

    return after;
}

static int check_ap_is_existent(char *ssid)
{  
    /* scan */
    int l_ret = 0;
    
    l_ret = wpa_cli_scan();
    if (l_ret != 0) {
        LOGE("cmd_wpa_scan fail.");
        return -1;
    }

    usleep(500 * 1000);
    
    /* get scan results */
    struct wpa_ap_info *pst_results = NULL;
    unsigned int   num = WIFI_MAX_NUM ;
    unsigned int   ul_loop;

    pst_results = malloc(sizeof(struct wpa_ap_info) * WIFI_MAX_NUM);
    if(NULL == pst_results) {
          LOGE("cmd_wpa_scan_results, OAL_PTR_NULL == pst_results\n");
          return -1;
    }
    
    memset(pst_results, 0, (sizeof(struct wpa_ap_info) * WIFI_MAX_NUM));
    wpa_cli_scan_results(pst_results, &num);
    for (ul_loop = 0; (ul_loop < num) && (ul_loop < WIFI_MAX_NUM); ul_loop++)
    {
        LOGD("ssid:%s\n", pst_results[ul_loop].ssid);
        if (strcmp(ssid, pst_results[ul_loop].ssid) == 0) {
            free(pst_results);
            pst_results = NULL;
            LOGD("exist the ap ssid %s\n", ssid);
            return 1;
        }
    }
    LOGD("dont't exist the ap ssid %s\n", ssid);
    free(pst_results);
    pst_results = NULL;

    return 0;
}


int hi1131s_check_ssid_is_existent(char *ssid)
{  
    /* scan */
    int l_ret = 0;
    
    l_ret = wpa_cli_scan();
    if (l_ret != 0) {
        LOGE("cmd_wpa_scan fail.");
        return -1;
    }

    usleep(500 * 1000);
    
    /* get scan results */
    struct wpa_ap_info *pst_results = NULL;
    unsigned int   num = WIFI_MAX_NUM ;
    unsigned int   ul_loop;

    pst_results = malloc(sizeof(struct wpa_ap_info) * WIFI_MAX_NUM);
    if(NULL == pst_results) {
          LOGE("cmd_wpa_scan_results, OAL_PTR_NULL == pst_results\n");
          return -1;
    }
    
    memset(pst_results, 0, (sizeof(struct wpa_ap_info) * WIFI_MAX_NUM));
    wpa_cli_scan_results(pst_results, &num);
    for (ul_loop = 0; (ul_loop < num) && (ul_loop < WIFI_MAX_NUM); ul_loop++)
    {
        LOGD("ssid:%s\n", pst_results[ul_loop].ssid);
        if (strcmp(ssid, pst_results[ul_loop].ssid) == 0) {
            free(pst_results);
            pst_results = NULL;
            LOGD("exist the ap ssid %s\n", ssid);
            return 1;
        }
    }
    LOGD("dont't exist the ap ssid %s\n", ssid);
    free(pst_results);
    pst_results = NULL;

    return 0;
}

static int wifi_get_config(char *ssid, char *password, char *encrypt)
{
#ifdef DEV_CONFIG
    DevConfigGetWifi(ssid, password, encrypt);
    if (ssid != NULL && strlen(ssid) == 0)
    {
        if (ssid != NULL) {
            ConfigGetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_SSID, ssid);        
        }
        if (password != NULL) {
            ConfigGetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_PASSWORD, password);
        }
        if (encrypt != NULL) {
            ConfigGetEnv(ENV_WIFI_TOKEN, ENV_WIFI_ENCRYPT, encrypt);
        }
    }
#else
    if (ssid != NULL) {
        ConfigGetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_SSID, ssid);
    }
    if (password != NULL) {
        ConfigGetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_PASSWORD, password);
    }
    if (encrypt != NULL) {
        ConfigGetEnv(ENV_WIFI_TOKEN, ENV_WIFI_ENCRYPT, encrypt);
    }
#endif /* DEV_CONFIG */
    return 0;
}

static int wifi_set_config(char *ssid, char *password, char *encrypt)
{
#ifdef DEV_CONFIG
    DevConfigSetWifi(ssid, password, encrypt);
#else
    ConfigSetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_SSID, ssid);
    ConfigSetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_PASSWORD, password);
    ConfigSetEnv(ENV_WIFI_TOKEN, ENV_WIFI_ENCRYPT, encrypt);
    ConfigSave();
#endif /* DEV_CONFIg */
    return 0;
}

void *MCGetRegisterStatus(void*args)
{
	DOTRegisterSetLock();
	for (int i = 0; i < 120; i++)
	{
		LOGW("MCGetRegisterStatus,i=%d\n", i);
		if (MC_get_register_status())
		{
			DOTRegisterSetUnlock();
			return;
		}
		sleep(1);
	}
	while (AudioGetOpsHandle()->play_file_start(AUDIO_CONFIG_FAIL, AUDIO_TYPE_MP3, 0) < 0) {
		 usleep(100 * 1000);
	}
	//	WifiSetDefaultConfig();
	sleep(5);
	//	SystemReboot("yd register failed");
	DOTRegisterSetUnlock();
	PowerSetSocSleepTime(AV_TRUE, 5);

}

void *tskWifiProc(void*args)
{
    SET_THREAD_NAME("tskWifiProc");
    pthread_detach(pthread_self());  
    
	UINT32 uwRet = 0;

    /* WiFi init */
    hi1131_wifi_init();
    
#ifdef WIFI_TEST_MODE
    return NULL;
#endif
     /* Detecting whether WiFi needs to be reconnected */
    if (!gs_wakeFlag) //非远程WiFi唤醒
    {
        while (!gs_wpasupplicantRunOk) {
            LOGD("gs_wpasupplicantRunOk: %d\n", gs_wpasupplicantRunOk);
            usleep(50 * 1000);
        }
        
        hi1131s_set_connect_local_wifi();  
    }
    else  //远程WiFi唤醒
    {
        /* 关闭上次休眠心跳的发送 */
        hisi_wlan_set_keepalive_switch(HISI_KEEPALIVE_OFF, 0);

        char dns1[16] = "";
        char dns2[16] = "";
        DevConfigGetWifiDns(dns1, dns2);
        NetSetDns(dns1, dns2);
        gs_wpaEvent = WPA_EVT_CONNECTED;

        /* run dhcp */
//        hisi_wifi_event_cb(WPA_EVT_CONNECTED);
    }

    char ssid[32] = "";
    int connect_count_num = 0;
    int reconnectTime = 0;
    char bExistentAp = 0;

    wifi_get_config(ssid, NULL, NULL);
    
    while (1)
    {
        if (gs_enWifiConfigState > WIFI_CONFIG_NONE)
        {
            if (gs_enWifiConfigState == WIFI_CONFIG_SOUNDWAVE_START) //声波接收开始 红灯闪烁
            {
                LedSet(LED_TYPE_RED, LED_STATE_BLINK, LED_LEVEL_LOW);
            }
            else if (gs_enWifiConfigState == WIFI_CONFIG_CONNECT_START) //WiFi连接开始 红灯快闪
            {
                LedSet(LED_TYPE_RED, LED_STATE_FAST_BLINK, LED_LEVEL_LOW);
                /* 统计连接时长,超过指定时长则恢复配置标识,保证指示灯正确显示 */
                if (gs_wpaEvent == WPA_EVT_DISCONNECTED) {
                    if (connect_count_num++ >= 100) { //100 * 100ms = 10s
                        gs_enWifiConfigState = WIFI_CONFIG_CONNECT_FAILED;
                        connect_count_num = 0;
//                        AudioGetOpsHandle()->play_file_start(AUDIO_LINK_FAIL, AUDIO_TYPE_MP3, 0);
                    }
                } else if (gs_wpaEvent == WPA_EVT_CONNECTED) {
                    gs_enWifiConfigState = WIFI_CONFIG_CONNECT_SUCCESS;
#ifndef MINI_APP
                    #ifdef ZDK_PROTOCOL
                    RealTimeServerClose();
                    #endif /* ZDK_PROTOCOL */
#endif /* MINI_APP */

					/* add alive time to resolve binding failure problem */
					PowerSetSocSleepTime(AV_TRUE, 30);

                    LOGI(">>>>>>>>>>>> success to connect wifi <<<<<<<<<<<<\n");
                    while (AudioGetOpsHandle()->play_file_start(AUDIO_LINK_SUCCESS, AUDIO_TYPE_MP3, 0) < 0) {
                    	usleep(100 * 1000);
                    }                    
                    sleep(1);
#ifndef MINI_APP                    
					#ifdef ZDK_PROTOCOL
                    RealTimeServerReStart();
					#endif
#endif /* MINI_APP */

			#ifdef YD_PROTOCOL
			pthread_t MCGetServerStatusPid;
			int err = pthread_create(&MCGetServerStatusPid, NULL, &MCGetRegisterStatus, NULL);
			if (err != 0) {
				LOGE("pthread_create MCGetServerStatus failed!\n");
				return -1;
			}
			#endif
                }
            }
        }
        else 
        {
            //LOGD("gs_wpaEvent %d reconnectTime:%d bExistentAp:%d\n", gs_wpaEvent, reconnectTime, bExistentAp);
            if (gs_wpaEvent == WPA_EVT_CONNECTED)
            {
                reconnectTime = 0;
                bExistentAp = 0;
                LedSet(LED_TYPE_BLUE, LED_STATE_ON, LED_LEVEL_LOW);

                static char bCheckDns = 0;
                if (bCheckDns == 0 && gs_bDhcpOk == 1) {
                    char dns1[16] = "";
                    char dns2[16] = "";
                    NetGetDns(dns1, dns2);
                    DevConfigSetWifiDns(dns1, dns2);
                    bCheckDns = 1;
                }
            }
            else if (gs_wpaEvent == WPA_EVT_DISCONNECTED)
            {
                static int runTimeMs = 0;

                if (runTimeMs < 10000) { //10s
                    usleep(100 * 1000);
                    runTimeMs += 100;
                    continue;
                }
                
                LedSet(LED_TYPE_RED, LED_STATE_ON, LED_LEVEL_LOW);

                if (gs_bStopStaMode) {
                    usleep(500 * 1000);
                    continue;
                }
                
                if (!bExistentAp)
                {
                    memset(ssid, 0, sizeof(ssid));
                    wifi_get_config(ssid, NULL, NULL);
                    char bHex = 0;
                    char ssidStr[32*4+1] = "";
                    
                    snprintf(ssidStr, sizeof(ssidStr), "%s", wifi_ssid_conver(ssid, &bHex));
                    if (strlen(ssidStr) > 0 && check_ap_is_existent(ssidStr) == 1) {
                        bExistentAp = 1;
                    }
                }

                if (bExistentAp)
                {
                    if (reconnectTime == 0) {
                        hi1131s_set_connect_local_wifi();
                    } else {
                        if (reconnectTime > 30 * 10) { //30s
                            reconnectTime = 0;
                            bExistentAp = 0;
                            continue;
                        }
                    }
                    reconnectTime++;                    
                }
            }
        }
        usleep(100*1000);
    }
    pthread_exit(0);
}

static int wifi_config_run()
{
    if (UpgradeCheckIsRun()) {
        LOGW("upgrade is running!\n");
        return -1;
    }

    int ret = 0;

    LOGI("wifi config run ......\n");
    gs_enWifiConfigState = WIFI_CONFIG_SOUNDWAVE_START; //notify red led blink

#ifdef YD_PROTOCOL
    #ifdef QRCODE_ENABLE
	if (WifiCheckIsConnected()) {
		WifiSetDisconnect();
		DOTHejiaguhuaDeInit();
	}
	PowerSetSocSleepTime(AV_TRUE, 60);
	QrcodeScanStart();
	AudioGetOpsHandle()->play_file_start(AUDIO_START_CON, AUDIO_TYPE_MP3, 0);
	DOTStartBind(4);
    #endif /* QRCODE_ENABLE */
#else
    char ssid[32] = "";
    char password[64] = "";
    WIFI_ENCRYPT_TYPE_E enEncryptType = WIFI_ENCRYPT_NULL;

    PowerSetWakeLock("WIFI");

    AudioGetOpsHandle()->play_file_start(AUDIO_START_CON, AUDIO_TYPE_MP3, 0);

#ifndef MINI_APP
    #ifdef ZDK_PROTOCOL
    RealTimeServerClose();
    #endif /* ZDK_PROTOCOL */
#endif /* MINI_APP */

    WifiSetDisconnect();

#ifndef MINI_APP
#ifdef SOUND_WAVE
    ret = SoundWaveWifiProcess(ssid, password);
    if (ret < 0) {
        LOGE("SoundWaveWifiProcess failed\n");
		#ifdef ZDK_PROTOCOL
        RealTimeServerReStart();
		#endif
        goto over_return;
    }
#endif /* SOUND_WAVE */

    #ifdef ZDK_PROTOCOL
    RealTimeServerClose();
    #endif /* ZDK_PROTOCOL */
#endif /* MINI_APP */
	
    if (strlen(password) == 0) {
        enEncryptType = WIFI_ENCRYPT_OPEN;
    } else {
        enEncryptType = WIFI_ENCRYPT_WPA_WPA2;
    }

    WifiSetConnect(ssid, password, enEncryptType);
    
over_return:
    gs_enWifiConfigState = WIFI_CONFIG_NONE;
    PowerSetWakeUnLock("WIFI");
#endif /* YD_PROTOCOL */

    return ret;
}

/**
 * @brief WiFi初始化
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_init(void)
{
    int ret = 0;
    pthread_t pidInit;

    hisi_log_level_switch(0x1);
        
    ret = pthread_create(&pidInit, NULL, &tskWifiProc, NULL);
    if (ret != 0) {
        LOGE("pthread_create tskWifiProc failed!\n");
        return -1;
    }
    
    KeyEventRegister(KEY_TYPE_CONFIG, KEY_STATE_PRESSED, wifi_config_run);

	return 0;
}

/**
 * @brief 连接WiFi,并保存配置
 *
 * @param[in] ssid 热点名称
 * @param[in] pwd  热点密码
 * @param[in] enEncryptType 加密类型
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_set_connect(char *ssid, char *pwd, WIFI_ENCRYPT_TYPE_E enEncryptType)
{
    int ret = 0;
    char ssidStr[32] = "";
    char pwdStr[64] = "";
    char encryptStr[32] = "";
    char bHex = 0;
	
    wifi_ssid_conver(ssid, &bHex);
    
    snprintf(ssidStr, sizeof(ssidStr), "%s", ssid);
    snprintf(pwdStr, sizeof(pwdStr), "%s", pwd);

    switch (enEncryptType)
    {
        case WIFI_ENCRYPT_OPEN:
            snprintf(encryptStr, sizeof(encryptStr), "%s", "open");
            break;
        case WIFI_ENCRYPT_WPA:
            snprintf(encryptStr, sizeof(encryptStr), "%s", "wpa");
            break;
        case WIFI_ENCRYPT_WPA2:
            snprintf(encryptStr, sizeof(encryptStr), "%s", "wpa2");
            break;
        case WIFI_ENCRYPT_WEP:
            snprintf(encryptStr, sizeof(encryptStr), "%s", "wep");
            break;
        case WIFI_ENCRYPT_WPA_WPA2:
            snprintf(encryptStr, sizeof(encryptStr), "%s", "wpa+wpa2");
            break;
    }

    LOGI("ssid: %s pwd: %s encrypt: %s\n", ssidStr, pwdStr, encryptStr);

    int argc = 0;
    char *argv[5] = {NULL};
    
    if (bHex) {
        argc = 5;
        argv[0] = "0";
        argv[1] = ssidStr;
        argv[2] = encryptStr;
        argv[3] = pwdStr;
        argv[4] = "1";
    } else {
        argc = 4;
        argv[0] = "0";
        argv[1] = ssidStr;
        argv[2] = encryptStr;
        argv[3] = pwdStr;
    }

    WifiSetDisconnect();
    usleep(100*1000);
//    gs_enWifiConfigState = WIFI_CONFIG_CONNECT_START; //notify red led fast blink

    
    int timeout = 0;
    int reconnectCnt = 0;
    
retry_connect:
    timeout = 600; //timeout wait 30s
    gs_enWifiConfigState = WIFI_CONFIG_CONNECT_START; //notify red led fast blink
	
	PowerSetSocSleepTime(AV_TRUE, 35);
    
    LOGI(">>>>>>>>>>>> start connect wifi <<<<<<<<<<<<\n");
 	ret = cmd_wpa_connect(argc, argv);
	if(0 != ret) {
		LOGE("fail to send wpa connect command\n");
		while (AudioGetOpsHandle()->play_file_start(AUDIO_LINK_FAIL, AUDIO_TYPE_MP3, 0) < 0) {
			usleep(100 * 1000);
		}
	    goto over_return;
	}

    while (timeout--)
    {
        if (gs_enWifiConfigState == WIFI_CONFIG_CONNECT_FAILED) 
        {
            if (reconnectCnt < 1) { //重连两次,每次10s
                LOGW("\n\n >>>>>>>>>>>>>>>> reconnect wifi \n\n");
                reconnectCnt++;
                goto retry_connect;
            } else {
                AudioGetOpsHandle()->play_file_start(AUDIO_LINK_FAIL, AUDIO_TYPE_MP3, 0);
                break;
            }
            reconnectCnt++;
        } 
        else if (gs_enWifiConfigState == WIFI_CONFIG_CONNECT_SUCCESS) 
        {
            wifi_set_config(ssidStr, pwdStr, encryptStr);        
            break;
        }
        usleep(50 * 1000);
    }
    
over_return:
    gs_enWifiConfigState = WIFI_CONFIG_NONE;

    return 0;
}

/**
 * @brief 断开WiFi连接
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_set_disconnect(void)
{
    wpa_cli_disconnect();

    return 0;
}

/**
 * @brief 连接配置中已保存的WiFi
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_set_connect_local_wifi(void)
{
    LOGD("test\b");
    
    UINT32 uwRet = 0;
    
     /* get wifi info from config */
    char ssid[32] = "";
    char password[64] = "";
    char encrypt[32] = "";
    
    wifi_get_config(ssid, password, encrypt);
    if (strlen(ssid) == 0) {
        LOGE("ssid is blank\n");
        return -1;
    }
    int argc = 4;
    char *argv[] = {"0", ssid, encrypt, password};

    uwRet = cmd_wpa_connect(argc, argv);
    if(0 != uwRet) {
        LOGE("fail to send wpa connect command\n");
    }
    
    return 0;
}

/**
 * @brief 获取WiFi状态
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_get_status(WIFI_STATUS_INFO_S *pstStatusInfo)
{
    if (pstStatusInfo == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }

    if (gs_bStopStaMode) {
        return -1;
    }

//    if (!gs_wpasupplicantRunOk) {
//        pstStatusInfo->connectionStatus = WIFI_DISCONNECTED;
//        return -1;
//    }
    
    int ret = 0;

    /* get wifi connnect status */
    switch (gs_wpaEvent)
    {
        case WPA_EVT_SCAN_RESULTS:
            break;
        case WPA_EVT_CONNECTED:
            pstStatusInfo->connectionStatus = WIFI_CONNECTED;
            break;
        case WPA_EVT_DISCONNECTED:
            pstStatusInfo->connectionStatus = WIFI_DISCONNECTED;
            break;
        case WPA_EVT_ADDIFACE:
            break;
        case WPA_EVT_WRONGKEY:
            break;
    }

    /* get wifi singnal */
    struct station_info staInfo;
    memset(&staInfo, 0, sizeof(staInfo));
    ret = hisi_wlan_get_station(&staInfo);
    if (ret != 0) {
        //LOGE("hisi_wlan_get_station failed\n");
        return -1;
    }
    pstStatusInfo->signalLevel = staInfo.l_signal + 100;

    /* get wifi ssid */
    char ssid[32] = "";
    wifi_get_config(ssid, NULL, NULL);
    snprintf(pstStatusInfo->ssid, sizeof(ssid), "%s", ssid);

    return 0;
}

/**
 * @brief 获取周边WiFi列表信息
 *
 * @param[in] pstWifiListInfo WIFI列表信息
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_get_list_info(WIFI_LIST_INFO_S *pstWifiListInfo)
{
    if (pstWifiListInfo == NULL) {
        LOGE("Params is invalid!\n");
        return -1;
    }

    int ret = 0;
    char currentSsid[32] = "";
    wifi_get_config(currentSsid, NULL, NULL);

    ret = wpa_cli_scan();
    if (ret != 0) {
        LOGE("cmd_wpa_scan fail\n");
        return -1;
    }
    
    usleep(500 * 1000);
    
    /* get scan results */
    struct wpa_ap_info *pst_results = NULL;
    unsigned int   num = WIFI_MAX_NUM ;
    unsigned int   ul_loop;

    pst_results = malloc(sizeof(struct wpa_ap_info) * WIFI_MAX_NUM);
    if(NULL == pst_results) {
          LOGE("cmd_wpa_scan_results, OAL_PTR_NULL == pst_results\n");
          return -1;
    }

    memset(pst_results, 0, (sizeof(struct wpa_ap_info) * WIFI_MAX_NUM));
    wpa_cli_scan_results(pst_results, &num);
    pstWifiListInfo->cnt = num;
    for (ul_loop = 0; (ul_loop < num) && (ul_loop < WIFI_MAX_NUM); ul_loop++)
    {
        //LOGD("ssid:%s\n", pst_results[ul_loop].ssid);
        snprintf(pstWifiListInfo->astAttrInfo[ul_loop].bssid, sizeof(pstWifiListInfo->astAttrInfo[ul_loop].bssid), "%s", pst_results[ul_loop].bssid);
        snprintf(pstWifiListInfo->astAttrInfo[ul_loop].ssid, sizeof(pstWifiListInfo->astAttrInfo[ul_loop].ssid), "%s", pst_results[ul_loop].ssid);
        
        switch (pst_results[ul_loop].auth)
        {
            case WPA_SECURITY_OPEN:
                pstWifiListInfo->astAttrInfo[ul_loop].mode = WIFI_ENCRYPT_OPEN;
                break;
            case WPA_SECURITY_WEP:
                pstWifiListInfo->astAttrInfo[ul_loop].mode = WIFI_ENCRYPT_WEP;
                break;
            case WPA_SECURITY_WPAPSK:
                pstWifiListInfo->astAttrInfo[ul_loop].mode = WIFI_ENCRYPT_WPA;
                break;
            case WPA_SECURITY_WPA2PSK:
                pstWifiListInfo->astAttrInfo[ul_loop].mode = WIFI_ENCRYPT_WPA2;
                break;
            case WPA_SECURITY_WPAPSK_WPA2PSK_MIX:
                pstWifiListInfo->astAttrInfo[ul_loop].mode = WIFI_ENCRYPT_WPA_WPA2;
                break;
        }
        if (strcmp(currentSsid, pst_results[ul_loop].ssid) == 0) {
            pstWifiListInfo->astAttrInfo[ul_loop].bConnected = 1;
        }        
        pstWifiListInfo->astAttrInfo[ul_loop].bHidden = 0;
        pstWifiListInfo->astAttrInfo[ul_loop].signaLevel = pst_results[ul_loop].rssi;
        pstWifiListInfo->astAttrInfo[ul_loop].noiseLevel = 0;
    }

    free(pst_results);
    pst_results = NULL;

    return 0;
}

/**
 * @brief 获取WiFi连接状态
 *
 * @param 无
 * 
 * @return |1|连接| |0|未连接|
 *
 * @attention 无
 */
int hi1131s_get_link_status()
{
	WIFI_STATUS_INFO_S stStatusInfo;
	memset(&stStatusInfo, 0, sizeof(stStatusInfo));
	WifiGetStatus(&stStatusInfo);
	if(WIFI_CONNECTED == stStatusInfo.connectionStatus){
		return 1;
	}

    return 1;
}

/**
 * @brief 获取WiFi唤醒原因 枚举hisi_wow_wakeup_reason_type_enum
 *
 * @param 无
 * 
 * @return |1|不处理| |0|需要设置唤醒表示为0|
 *
 * @attention 无
 */
int hi1131s_get_wakeup_reason(void)
{
    int quickLinkFlag = 1;
	int wakeup_reason_index = 0;
	char *wakeup_reason_str[] = {
		"HISI_WOW_WKUP_REASON_TYPE_NULL",        		/* None */
		"HISI_WOW_WKUP_REASON_TYPE_MAGIC_PACKET",    	/* Wakeup on Magic Packet */
		"HISI_WOW_WKUP_REASON_TYPE_NETPATTERN_TCP", 	/* Wakeup on TCP NetPattern */
		"HISI_WOW_WKUP_REASON_TYPE_NETPATTERN_UDP", 	/* Wakeup on UDP NetPattern */
		"HISI_WOW_WKUP_REASON_TYPE_DISASSOC_RX",        /* 对端去关联/去认证，Wakeup on Disassociation/Deauth */
		"HISI_WOW_WKUP_REASON_TYPE_DISASSOC_TX",        /* 对端去关联/去认证，Wakeup on Disassociation/Deauth */
		"HISI_WOW_WKUP_REASON_TYPE_AUTH_RX",  			/* 本端端关联请求，Wakeup on auth */
		"HISI_WOW_WKUP_REASON_TYPE_TCP_UDP_KEEP_ALIVE", /* Wakeup on TCP/UDP keep alive timeout */
		"HISI_WOW_WKUP_REASON_TYPE_HOST_WAKEUP", 		/* Host wakeup */
		"HISI_WOW_WKUP_REASON_TYPE_OAM_LOG",       		/* OAM LOG wakeup */
		"HISI_WOW_WKUP_REASON_TYPE_SSID_SCAN",      	/* SSID Scan wakeup */
		"HISI_WOW_WKUP_REASON_TYPE_BUT"
	};

	hisi_wlan_get_wakeup_reason(&wakeup_reason_index);
    switch (wakeup_reason_index)
    {
        case HISI_WOW_WKUP_REASON_TYPE_NULL:
        case HISI_WOW_WKUP_REASON_TYPE_MAGIC_PACKET:
        case HISI_WOW_WKUP_REASON_TYPE_NETPATTERN_TCP:
        case HISI_WOW_WKUP_REASON_TYPE_NETPATTERN_UDP:
            break;
        case HISI_WOW_WKUP_REASON_TYPE_DISASSOC_RX:
        case HISI_WOW_WKUP_REASON_TYPE_DISASSOC_TX:
        case HISI_WOW_WKUP_REASON_TYPE_AUTH_RX:
        case HISI_WOW_WKUP_REASON_TYPE_TCP_UDP_KEEP_ALIVE:
            quickLinkFlag  = 0;
            break;
        case HISI_WOW_WKUP_REASON_TYPE_HOST_WAKEUP:
        case HISI_WOW_WKUP_REASON_TYPE_OAM_LOG:
            break;
        case HISI_WOW_WKUP_REASON_TYPE_SSID_SCAN:
            quickLinkFlag  = 0;
            break;
    }
    
	printf("wifi wakeup reason: %s\n", wakeup_reason_str[wakeup_reason_index]);

	return quickLinkFlag ;
}


/**
 * @brief 设置默认WiFi配置
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_set_default_config(void)
{
    wifi_set_config("", "", "");
    ConfigSetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_SSID, "");
    ConfigSetEnv(ENV_WIFI_TOKEN, ENV_WIFI_KEY_PASSWORD, "");
    ConfigSave();

    hi1131s_set_disconnect();

    return 0;
}

/**
 * @brief 获取WiFi休眠配置
 *
 * @param[out] pstSleepAttr WiFi休眠属性
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_get_sleep_config(WIFI_SLEEP_ATTR_S *pstSleepAttr)
{
    char uuid[32] = "";
    int cnt = 0;

    DevGetUuid(uuid);
    snprintf(pstSleepAttr->heartBeatData, sizeof(pstSleepAttr->heartBeatData), 
                "{\"command\":\"300100\", \"client_id\":\"%s\"}", uuid);
    pstSleepAttr->heartBeatLen = strlen(pstSleepAttr->heartBeatData);
    strncpy(pstSleepAttr->wakeupData, "ZDKALIVE", sizeof(pstSleepAttr->wakeupData));

    snprintf(pstSleepAttr->server[cnt].ip, sizeof(pstSleepAttr->server[cnt].ip),
                "%s", "106.75.148.61");
    pstSleepAttr->server[cnt].port = 9508;
    cnt++;

#if 0 //debug
    snprintf(pstSleepAttr->server[cnt].ip, sizeof(pstSleepAttr->server[cnt].ip),
                "%s", "192.168.0.22");
    pstSleepAttr->server[cnt].port = 8888;
    cnt++;
#endif
    
    pstSleepAttr->serverNum = cnt;
    pstSleepAttr->wakeupLen = strlen(pstSleepAttr->wakeupData);
    pstSleepAttr->interval = 60; //10s
    
#ifdef ZDK_PROTOCOL
    DevGetUuid(uuid);
    snprintf(pstSleepAttr->heartBeatData, sizeof(pstSleepAttr->heartBeatData), 
                "{\"command\":\"300100\", \"client_id\":\"%s\"}", uuid);
    pstSleepAttr->heartBeatLen = strlen(pstSleepAttr->heartBeatData);
    strncpy(pstSleepAttr->wakeupData, "ZDKALIVE", sizeof(pstSleepAttr->wakeupData));

    snprintf(pstSleepAttr->server[cnt].ip, sizeof(pstSleepAttr->server[cnt].ip),
                "%s", "106.75.148.61");
    pstSleepAttr->server[cnt].port = 9508;
    cnt++;

#if 0 //debug
    snprintf(pstSleepAttr->server[cnt].ip, sizeof(pstSleepAttr->server[cnt].ip),
                "%s", "192.168.0.22");
    pstSleepAttr->server[cnt].port = 8888;
    cnt++;
#endif
    
    pstSleepAttr->serverNum = cnt;
    pstSleepAttr->wakeupLen = strlen(pstSleepAttr->wakeupData);
    pstSleepAttr->interval = 60; //10s
#elif YD_PROTOCOL
	/*cc_hb_config config ;
	int i;
	
    memset(&config,0,sizeof(config));
	printf("\n\n\n\nWifiGetSleepConfig1\n\n\n");
    cc_api_suspend(&config);
	printf("\n\n\n\nWifiGetSleepConfig2\n\n\n");
	printf("config.heartbeatrequest = %s\n",config.heartbeatrequest);
	printf("config.heartbeatrequestlen = %d\n",config.heartbeatrequestlen);
	printf("config.wakeuprequest = %s\n",config.wakeuprequest);
	printf("config.wakeuprequestlen = %d\n",config.wakeuprequestlen);
	printf("config.servernum = %d\n",config.servernum);
	printf("config.interval = %d\n",config.interval);
    if(0 == i)   //获取保活服务器信息
    {
        //memcpy(pstSleepAttr, &config, sizeof(cc_hb_config));
        strcpy(pstSleepAttr->heartBeatData, config.heartbeatrequest);
		pstSleepAttr->heartBeatLen = config.heartbeatrequestlen;
		strcpy(pstSleepAttr->wakeupData, config.wakeuprequest);
		pstSleepAttr->wakeupLen = config.wakeuprequestlen;
		pstSleepAttr->serverNum = config.servernum;
		pstSleepAttr->interval = config.interval;
		for (i = 0; i < 4; i++)
		{
			strcpy(pstSleepAttr->server[i].ip, config.serverport[i].server);
			pstSleepAttr->server[i].port = config.serverport[i].port;
			printf("pstSleepAttr->server[%d].ip = %s\n",i,pstSleepAttr->server[i].ip);
			printf("pstSleepAttr->server[%d].port = %d\n",i,pstSleepAttr->server[i].port);
		}
		printf("pstSleepAttr->heartBeatData = %s\n",pstSleepAttr->heartBeatData);
		printf("config.heartbeatrequest = %s\n",config.heartbeatrequest);
		printf("pstSleepAttr->heartBeatLen = %d\n",pstSleepAttr->heartBeatLen);
		printf("pstSleepAttr->wakeupData = %s\n",pstSleepAttr->wakeupData);
		printf("config.wakeuprequest = %s\n",config.wakeuprequest);
		printf("pstSleepAttr->wakeupLen = %d\n",pstSleepAttr->wakeupLen);
		printf("pstSleepAttr->serverNum = %d\n",pstSleepAttr->serverNum);
		printf("pstSleepAttr->interval = %d\n",pstSleepAttr->interval);
    }*/ 
#elif TELECOM

#endif
    return 0;
}

/**
 * @brief 设置WiFi休眠心跳
 *
 * @param[in] stSleepAttr WiFi休眠属性
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_set_sleep_heartbeat(WIFI_SLEEP_ATTR_S stSleepAttr)
{
    LOGI("test\n");
    
    int ret = 0;
    
    ret = keepalive_create_heartbeat(stSleepAttr);
    if (ret < 0) {
        LOGE("keepalive_create_heartbeat failed\n");
        return -1;
    }

    return 0;
}

/**
 * @brief 设置WiFi进入休眠模式
 *
 * @param 无
 * 
 * @return |0|成功| |-1|创建心跳失败| |-2|不允许休眠,检测到系统正在升级|
 *
 * @attention 无
 */
int hi1131s_set_sleep_mode(void)
{
	LOGI("test\n");

    int ret = 0;
    WIFI_SLEEP_ATTR_S stSleepAttr;

	//获取WiFi休眠配置
	memset(&stSleepAttr, 0, sizeof(stSleepAttr));
	ret = hi1131s_get_sleep_config(&stSleepAttr); 
	if (ret < 0) {
        LOGE("hi1131s_get_sleep_config failed\n");
        return -1;
	}

	//设置WiFi休眠心跳
    ret = hi1131s_set_sleep_heartbeat(stSleepAttr);
    if (ret < 0) {
        LOGE("hi1131s_set_sleep_heartbeat failed\n");
        return -1;
    }

    //设置WiFi唤醒方式功能开关
    hisi_wlan_set_wow_event(0x1DF);
    
    //设置唤醒包
    unsigned int ul_netpattern_index = 1;
    ret = hisi_wlan_add_netpattern(ul_netpattern_index, stSleepAttr.wakeupData, stSleepAttr.wakeupLen);
    if (ret != 0) {
        LOGE("hisi_wlan_add_netpattern failed\n");
        return -1;
    }

    //WiFi进入休眠
    if (UpgradeCheckIsRun()) {
        LOGW("upgrade is running, pause wifi sleep\n");
        return -2;
    }

	hisi_wlan_suspend();

	return 0;
}


int hi1131s_stop_sta_mode(void)
{
    gs_bStopStaMode = 1;

//    usleep(50 * 1000);
//    cmd_wpa_stop();
    
    return 0;
}

int hi1131s_run_sta(void)
{
    int                      l_ret;
    unsigned int             ul_ret;
    hsl_result_stru         *pst_result;
    struct netif            *pst_netif;

    /* 删除AP模式 */
    pst_netif = netif_find("wlan0");
    if (HSL_NULL != pst_netif) {
        netifapi_dhcps_stop(pst_netif);
    }

#if 0
    if (WIFI_MODE_STA == gs_enWifiMode) {
        HISI_PRINT_INFO("wpa_supplicant is allready started!");
        return -1;
    }
#endif
    
    l_ret = hostapd_stop();
    if (0 != l_ret) {
        LOGE("hostapd stop failed\n");
        return -1;
    }
    init_completion(&dhcp_complet);
    
#ifdef CONFIG_NO_CONFIG_WRITE
    l_ret = wpa_supplicant_start("wlan0", "hisi", HSL_NULL);
#else
    l_ret = wpa_supplicant_start("wlan0", "hisi", WPA_SUPPLICANT_CONFIG_PATH);
#endif
    if (0 != l_ret) {
        LOGE("start wpa_supplicant failed\n");
        return -1;
    }
#if 0
    ul_ret = wait_for_completion_timeout(&dhcp_complet, LOS_MS2Tick(40000));//40s超时
    if (0 == ul_ret)
    {
        HISI_PRINT_ERROR("hsl_demo_connect_prepare:cannot get ip\n");
        return -HSL_FAIL;
    }
    pst_result = hsl_demo_get_result();
    if (HSL_NULL != pst_result)
    {
        hsl_demo_online(pst_result);
    }
#endif

    /* wait wpa_supplicant ok */
    int waitSupplicantOkCount = 0;
    while (!gs_wpasupplicantRunOk) {
        if (waitSupplicantOkCount > 100) { // timeout 5s
            LOGE("wpa_supplicant start failed\n");
            return -1;
        }
        usleep(50 * 1000);
        waitSupplicantOkCount++;
    }
    
    LOGI(">>> wpa_supplicant start success");
    
    gs_enWifiMode = WIFI_MODE_STA;

    return 0;
}

int hi1131s_run_ap(WIFI_AP_CONFIG_S stApConfig)
{
    int            l_ret;
    char           ac_ssid[33];
    unsigned char  auc_password[65];
    unsigned int   ul_ssid_len = 0;
    unsigned int   ul_pass_len = 0;
    struct netif  *pst_netif;
    ip4_addr_t      st_gw;
    ip4_addr_t      st_ipaddr;
    ip4_addr_t      st_netmask;
    struct hostapd_conf hapd_conf;

    /* 尝试删除wpa_supplicant和hostapd */
    l_ret = wpa_supplicant_stop();
    if (0 != l_ret) {
        LOGE("wpa_supplicant stop failed\n");
    }
    
    pst_netif = netif_find("wlan0");
    if (NULL != pst_netif) {
        netifapi_dhcps_stop(pst_netif);
    }

#if 0
    if (WIFI_MODE_AP == gs_enWifiMode) {
        HISI_PRINT_INFO("hostapd is allready started!");
        return -1;
    }
#endif
    
    l_ret = hostapd_stop();
    if (0 != l_ret) {
        LOGE("hostapd stop failed\n");
    }

    /* 设置网口信息 */
    IP4_ADDR(&st_gw, 192, 168, 43, 1);
    IP4_ADDR(&st_ipaddr, 192, 168, 43, 1);
    IP4_ADDR(&st_netmask, 255, 255, 255, 0);
    netifapi_netif_set_addr(pst_netif, &st_ipaddr, &st_netmask, &st_gw);

    memset(&hapd_conf, 0, sizeof(hapd_conf));
    memcpy(hapd_conf.driver, "hisi", 5);
    snprintf(hapd_conf.ssid, sizeof(hapd_conf.ssid), "%s", stApConfig.ssid);
    hapd_conf.ignore_broadcast_ssid = 0;
    snprintf(hapd_conf.ht_capab, sizeof(hapd_conf.ht_capab), "%s", "[HT20]");
    
    hapd_conf.channel_num           = stApConfig.channel;

    switch (stApConfig.mode)
    {
        case WIFI_ENCRYPT_OPEN:
            hapd_conf.authmode              = HOSTAPD_SECURITY_OPEN;
            break;
        case WIFI_ENCRYPT_WPA:
            hapd_conf.authmode              = HOSTAPD_SECURITY_WPAPSK;
            hapd_conf.wpa_pairwise          = WPA_CIPHER_TKIP | WPA_CIPHER_CCMP;
            hapd_conf.wpa                   = 2;
            snprintf(hapd_conf.key, sizeof(hapd_conf.ssid), "%s", stApConfig.password);
            break;
        case WIFI_ENCRYPT_WPA2:
            hapd_conf.authmode              = HOSTAPD_SECURITY_WPA2PSK;
            hapd_conf.wpa_pairwise          = WPA_CIPHER_TKIP | WPA_CIPHER_CCMP;
            hapd_conf.wpa                   = 2;
            snprintf(hapd_conf.key, sizeof(hapd_conf.ssid), "%s", stApConfig.password);
            break;
        case WIFI_ENCRYPT_WPA_WPA2:
            hapd_conf.authmode              = HOSTAPD_SECURITY_WPAPSK_WPA2PSK_MIX;
            hapd_conf.wpa_pairwise          = WPA_CIPHER_TKIP | WPA_CIPHER_CCMP;
            hapd_conf.wpa                   = 2;
            snprintf(hapd_conf.key, sizeof(hapd_conf.ssid), "%s", stApConfig.password);
            break;
    }

    /* 重新设置netif的网关和mac地址，防止STA切AP时，没有还原 */
    netifapi_netif_set_addr(pst_netif, &st_ipaddr, &st_netmask, &st_gw);
    if (NULL != pst_netif) {
//        gst_hapd_conf.beacon_int = atoi(puc_beacon_int);
    }

    if (HISI_SUCC != hostapd_start(HISI_NULL, &hapd_conf)) {
        LOGE("hostapd start failed");
        return -1;
    }

    LOGI(">>> hostapd start success");

    gs_enWifiMode = WIFI_MODE_AP;
    
    return 0;
}


/**
 * @brief 切换WiFi模式
 *
 * @param[in] stModeAttr 模式属性
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 若切换为AP模式,需填充AP配置. 切换STA模式,暂不需要填充配置
 */
int hi1131s_set_mode(WIFI_MODE_ATTR_S     stModeAttr)
{
    if (WIFI_MODE_STA == stModeAttr.enMode)
    {
        hi1131s_run_sta();
        gs_bStopStaMode = 0;
    }
    else if (WIFI_MODE_AP == stModeAttr.enMode)
    {
#if 0 //debug
        snprintf(stModeAttr.stApConfig.ssid, sizeof(stModeAttr.stApConfig.ssid), "%s", "B1");
        stModeAttr.stApConfig.channel = 13;
        stModeAttr.stApConfig.mode = WIFI_ENCRYPT_OPEN;
#endif
        gs_bStopStaMode = 1;
        gs_wpasupplicantRunOk = 0;
        /* run ap */
        hi1131s_run_ap(stModeAttr.stApConfig);
    }

    return 0;
}

/**
 * @brief WIFI去初始化
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 无
 */
int hi1131s_deinit(void)
{
     KeyEventUnRegister(KEY_TYPE_CONFIG, KEY_STATE_PRESSED, wifi_config_run);

     return 0;
}
#endif /* HISYSLINK_ENABLE */

